home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 16 code / CollaboDraw / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-24  |  13.0 KB  |  656 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------------------------
  2.  *
  3.  * Simple Sample PowerTalk Application Framework
  4.  *
  5.  * ©1991-1993 Apple Computer
  6.  *
  7.  -------------------------------------------------------------------------------------*/
  8. /*
  9.  * utils.c -- utility routines
  10.  *
  11.  * change history:
  12.  *
  13.  * SJF        08/23/93        1.0f1        update to final headers, fix comments
  14.  * SJF        04/21/93        1.0b2        update to b2
  15.  * SJF        03/01/93        1.0b1        added digital signatures
  16.  * SJF        02/09/93        1.0b1        update to b1
  17.  * SJF        10/13/92        1.0d4        update to a11
  18.  * SJF        09/09/92        1.0d3        update to a9
  19.  * SJF        05/07/92        1.0d2        update to a6
  20.  * SJF        11/06/91        1.0d1        initial coding
  21.  *
  22.  */
  23.  
  24. #pragma segment othersegment
  25.  
  26. #ifndef __TYPES__
  27. #include <Types.h>
  28. #endif
  29.  
  30. #ifndef __MENUS__
  31. #include <Menus.h>
  32. #endif
  33.  
  34. #ifndef __GESTALTEQU__
  35. #include <GestaltEqu.h>
  36. #endif
  37.  
  38. #ifndef __TRAPS__
  39. #include <Traps.h>
  40. #endif
  41.  
  42. #ifndef __NOTIFICATION__
  43. #include <Notification.h>
  44. #endif
  45.  
  46. #ifndef __TOOLUTILS__
  47. #include <ToolUtils.h>
  48. #endif
  49.  
  50. #ifndef __FILES__
  51. #include <Files.h>
  52. #endif
  53.  
  54. #ifdef THINK_C
  55. #include <BDC.h>    // workaround for think packages.h bug
  56. #endif
  57.  
  58. #ifndef __PACKAGES__
  59. #include <Packages.h>
  60. #endif
  61.  
  62. #ifndef __EVENTS__
  63. #include <Events.h>
  64. #endif
  65.  
  66. #ifndef __RESOURCES__
  67. #include <Resources.h>
  68. #endif
  69.  
  70. #ifndef __FOLDERS__
  71. #include <Folders.h>
  72. #endif
  73.  
  74. #ifndef __PALETTES__
  75. #include <Palettes.h>
  76. #endif
  77.  
  78. #ifndef __OCESTANDARDMAIL__
  79. #include <OCEStandardMail.h>
  80. #endif
  81.  
  82. #include "const.h"
  83. #include "mytypes.h"
  84. #include "globals.h"
  85. #include "trapavailable.h"
  86. #include "main.h"
  87. #include "mymenus.h"
  88. #include "strconst.h"
  89. #include "windowstuff.h"
  90.  
  91. #include "utils.h"
  92.  
  93. /* returns true if color quickdraw is available */
  94.  
  95. Boolean HasColorQD(void)
  96. {
  97.     SysEnvRec theEnv;
  98.     
  99.     if (SysEnvirons(1,&theEnv) != noErr)
  100.         return false;
  101.  
  102.     return (theEnv.hasColorQD);
  103. }
  104.  
  105.  
  106. /* handles an error by displaying an error string via the notification manager or alert */
  107.  
  108. void DoError(OSErr err)
  109. {
  110.     Str255 errStr;
  111.     Str255 errNumStr;
  112.     Handle resHandle;
  113.     
  114.     if (err==noErr)
  115.         return;
  116.     
  117.     if (resHandle=GetResource('Estr',err)) {    // get our list of error strings
  118.         HLock(resHandle);
  119.         pstrcpy(errStr,*resHandle);
  120.         HUnlock(resHandle);
  121.         ReleaseResource(resHandle);
  122.     }
  123.     else {
  124.         NumToString(err,errNumStr);
  125.         pstrcpy(errStr,"\pAn error has occurred: ");
  126.         pstrcat(errStr,errNumStr);
  127.     }
  128.     
  129.     if (gInBackground)
  130.         Notify(errStr);
  131.     else {
  132.         ParamText(errStr,nil,nil,nil);
  133.         StopAlert(kErrorBoxID,nil);
  134.     }    
  135. }
  136.  
  137.  
  138. /* post our notification */
  139.  
  140. void Notify(StringPtr string)
  141. {
  142.     NMRecPtr nm;
  143.     StringPtr strPtr;
  144.     
  145.     nm = (NMRecPtr)NewPtr(sizeof(NMRec));
  146.     if (MemError()!=noErr)
  147.         return;
  148.     strPtr = (StringPtr)NewPtr(string[0]);
  149.     if (MemError()!=noErr)
  150.         return;
  151.     BlockMove(string,strPtr,string[0]+1);
  152.     
  153.     nm->qType = nmType;
  154.     nm->nmMark = 0;
  155.     nm->nmIcon = nil;
  156.     nm->nmSound = nil;
  157.     nm->nmStr = strPtr;
  158.     nm->nmResp = nil;
  159.     NMInstall(nm);
  160. }
  161.  
  162.  
  163. /* pascal string copy function */
  164.  
  165. void pstrcpy(void *dest,void *src)
  166. {
  167.     unsigned char srcLen = ((unsigned char *)src)[0];
  168.     
  169.     BlockMove(src,dest,srcLen+1);
  170. }
  171.  
  172.  
  173. /* pascal string catenation function */
  174.  
  175. void pstrcat(void *original,void *catStr)
  176. {
  177.     short length;
  178.     unsigned char originalLen = ((unsigned char *)original)[0];
  179.     unsigned char catStrLen = ((unsigned char *)catStr)[0];
  180.     
  181.     length = (short) originalLen;
  182.     length += (short) catStrLen;
  183.     
  184.     if (length > 255) {
  185.         DebugStr("\pstring catenation overflow");
  186.         ExitToShell();
  187.     }
  188.     
  189.     BlockMove((char *)catStr+1,(char *)original+originalLen+1,catStrLen);
  190.     ((unsigned char *)original)[0] = (unsigned char) length;
  191. }
  192.  
  193.  
  194. /* tries to get a given string out of the resource fork, and if it's not there, copy the */
  195. /* backup string into storage before returning */
  196.  
  197. void GetResString(StringPtr storage,short rezID,StringPtr backupString)
  198. {
  199.     StringHandle rezString;
  200.     
  201.     rezString = GetString(rezID);
  202.     if (rezString) {
  203.         pstrcpy(storage,*rezString);
  204.         ReleaseResource((Handle)rezString);
  205.     }
  206.     else
  207.         pstrcpy(storage,backupString);
  208. }
  209.  
  210.  
  211. /* memory manager NewPtr wrapper */
  212.  
  213. void *NewPtrChk(Size ptrSize)
  214. {
  215.     Ptr thePtr;
  216.  
  217.     thePtr = NewPtr(ptrSize);
  218.     if (MemError()!=noErr)
  219.         DoError(MemError());
  220. #if kDEBUG
  221.     {
  222.         long *longPtr = (long *)thePtr;
  223.         *longPtr = kBetterBusErr;
  224.     }
  225. #endif
  226.     return thePtr;
  227. }
  228.  
  229.  
  230. /* memory manager NewHandle wrapper */
  231.  
  232. void *NewHandleChk(Size hndlSize)
  233. {
  234.     Handle theHndl;
  235.     
  236.     theHndl = NewHandle(hndlSize);
  237.     if (MemError()!=noErr)
  238.         DoError(MemError());
  239. #if kDEBUG
  240.     {
  241.         long **longHndl = (long **)theHndl;
  242.         **longHndl = kBetterBusErr;
  243.     }
  244. #endif
  245.     return theHndl;
  246. }
  247.  
  248.  
  249. /* memory manager DisposPtr wrapper */
  250.  
  251. void DisposPtrChk(void *thePtr)
  252. {
  253. #if kDEBUG
  254.     {
  255.         long *longPtr = (long *)thePtr;
  256.         *longPtr = kBetterBusErr;
  257.     }
  258. #endif
  259.  
  260.     DisposPtr(thePtr);
  261.     if (MemError()!=noErr)
  262.         DoError(MemError());
  263. }
  264.  
  265.  
  266. /* memory manager DisposHandle wrapper */
  267.  
  268. void DisposHandleChk(void *theHndl)
  269. {
  270. #if kDEBUG
  271.     {
  272.         long **longHndl = (long **)theHndl;
  273.         **longHndl = kBetterBusErr;
  274.     }
  275. #endif
  276.  
  277.     DisposHandle(theHndl);
  278.     if (MemError()!=noErr)
  279.         DoError(MemError());
  280. }
  281.  
  282.  
  283. /* disables all of the menus in the menubar */
  284.  
  285. void DisableAllMenus(void)
  286. {
  287.     MenuHandle theMenu;
  288.     short menuIndex;
  289.     
  290.     for (menuIndex=kAppleMenu+1; menuIndex<kAppleMenu+kNumMenus; menuIndex++) {
  291.         theMenu = GetMHandle(menuIndex);
  292.         DisableItem(theMenu,0);
  293.     }
  294. }
  295.  
  296.  
  297. /* enables all of the menus in the menubar */
  298.  
  299. void EnableAllMenuItems(MenuHandle theMenu)
  300. {
  301.     short itemIndex,numItems;
  302.     
  303.     numItems = CountMItems(theMenu);
  304.     for (itemIndex=1; itemIndex<=numItems; itemIndex++)
  305.         EnableItem(theMenu,itemIndex);
  306.     EnableItem(theMenu,0);
  307. }
  308.  
  309.  
  310. /* sets up our default menu state */
  311.  
  312. void SetDefaultMenus(void)
  313. {
  314.     MenuHandle theMenu;
  315.         
  316.     DisableAllMenus();
  317.     theMenu = GetMHandle(kFileMenu);
  318.     EnableAllMenuItems(theMenu);
  319.     DisableItem(theMenu,kCloseItem);
  320.     DisableItem(theMenu,kSaveItem);
  321.     DisableItem(theMenu,kSaveAsItem);
  322.     DisableItem(theMenu,kPageSetupItem);
  323.     DisableItem(theMenu,kPrintItem);
  324.     
  325.     theMenu = GetMHandle(kEditMenu);
  326.     EnableAllMenuItems(theMenu);
  327.     DisableItem(theMenu,kUndoItem);
  328.     DisableItem(theMenu,kCutItem);
  329.     DisableItem(theMenu,kCopyItem);
  330.     DisableItem(theMenu,kPasteItem);
  331.     DisableItem(theMenu,kClearItem);
  332.     DisableItem(theMenu,kSelectAllItem);
  333.     
  334.     theMenu = GetMHandle(kMailMenu);
  335.     EnableAllMenuItems(theMenu);
  336.     DisableItem(theMenu,kAddRemMailItem);
  337.     DisableItem(theMenu,kSendItem);
  338.     DisableItem(theMenu,kReplyItem);
  339.     DisableItem(theMenu,kReplyToAllItem);
  340.     DisableItem(theMenu,kForwardItem);
  341.     DisableItem(theMenu,kTagLetterItem);
  342.  
  343.     theMenu = GetMHandle(kSignMenu);
  344.     DisableItem(theMenu,0);
  345. }
  346.  
  347.  
  348. /* sets up the undo command */
  349.  
  350. void SetUndoCommand(WindowPtr window,WInfoPtr infoPtr,const ShapeList *command)
  351. {
  352.     gCanUndo = true;
  353.     gHasUndo = false;
  354.     gUndoCommand.window = window;
  355.     gUndoCommand.theShape = *command;
  356.     gUndoCommand.windowRefCount = infoPtr->refCount;
  357. }
  358.  
  359.  
  360. /* clears the undo command */
  361.  
  362. void ClearAppUndo(void)
  363. {
  364.     gCanUndo = false;
  365.     gHasUndo = false;
  366. }
  367.  
  368.  
  369. /* sets the undo string to the appropriate command, if applicable */
  370.  
  371. Boolean SetupAppUndo(void)
  372. {
  373.     if (gCanUndo)
  374.         return SetUndoString(gUndoCommand.theShape.shapeType,gHasUndo);
  375.     else
  376.         return SetUndoString(0,false);
  377. }
  378.  
  379.  
  380. /* sets the undo string to the appropriate command */
  381.  
  382. Boolean SetUndoString(short commandID,Boolean redoFlag)
  383. {
  384.     Str255 undoString;
  385.     MenuHandle theMenu;
  386.     WInfoHndl infoHndl;
  387.     
  388.     if (redoFlag) {
  389.         switch (commandID) {
  390.             case kLineShape:
  391.                 GetResString(undoString,kRedoLineID,kRedoLine);
  392.                 break;
  393.             case kRectShape:
  394.                 GetResString(undoString,kRedoRectID,kRedoRect);
  395.                 break;
  396.             case kRoundRectShape:
  397.                 GetResString(undoString,kRedoRoundRectID,kRedoRoundRect);
  398.                 break;
  399.             case kOvalShape:
  400.                 GetResString(undoString,kRedoOvalID,kRedoOval);
  401.                 break;
  402.         }
  403.     }
  404.     else {
  405.         switch (commandID) {
  406.             case 0:
  407.                 GetResString(undoString,kUndoStringID,kUndoString);
  408.                 break;
  409.             case kLineShape:
  410.                 GetResString(undoString,kUndoLineID,kUndoLine);
  411.                 break;
  412.             case kRectShape:
  413.                 GetResString(undoString,kUndoRectID,kUndoRect);
  414.                 break;
  415.             case kRoundRectShape:
  416.                 GetResString(undoString,kUndoRoundRectID,kUndoRoundRect);
  417.                 break;
  418.             case kOvalShape:
  419.                 GetResString(undoString,kUndoOvalID,kUndoOval);
  420.                 break;
  421.         }
  422.     }
  423.     
  424.     theMenu = GetMHandle(kEditMenu);
  425.     SetItem(theMenu,kUndoItem,undoString);
  426.  
  427.     if (MyFrontWindow())
  428.         infoHndl = GetWindowInfo(MyFrontWindow());
  429.     
  430.     if (gCanUndo && MyFrontWindow() && ((**infoHndl).refCount==gUndoCommand.windowRefCount) &&
  431.             commandID!=0) {
  432.         EnableItem(theMenu,kUndoItem);
  433.         return true;
  434.     }
  435.     else {
  436.         DisableItem(theMenu,kUndoItem);
  437.         return false;
  438.     }
  439. }
  440.  
  441.  
  442. /* read our prefs global from disk */
  443.  
  444. void ReadPrefs(void)
  445. {
  446.     FSSpec prefsSpec;
  447.     short refNum;
  448.     long count;
  449.     OSErr err;
  450.     
  451.     refNum = 0;
  452.     
  453.     GetPrefsFolder(&prefsSpec);
  454.     err = FSpOpenDF(&prefsSpec,fsRdPerm,&refNum);
  455.     if (err!=noErr) {
  456.         err = FSpCreate(&prefsSpec,kAppCreator,kPrefsType,smRoman);
  457.         if (err==noErr)
  458.             err = FSpOpenDF(&prefsSpec,fsRdPerm,&refNum);
  459.     }
  460.     
  461.     if (err==noErr) {
  462.         count = sizeof(MyPreferences);
  463.         err = FSRead(refNum,&count,&gPreferences);
  464.         if (err==noErr && gPreferences.version!=kPrefsVersion)
  465.             err = -1;
  466.     }
  467.     
  468.     if (err!=noErr) {
  469.     
  470.         // set default preferences
  471.         
  472.         gPreferences.version = kPrefsVersion;
  473.         gPreferences.sendOptions.signWhenSent = false;
  474.         gPreferences.sendOptions.priority = kIPMNormalPriority;
  475.         gPreferences.closeOptions.moveToTrash = false;
  476.         gPreferences.closeOptions.addTag = false;
  477.         gPreferences.closeOptions.tag.dataLength = 0;
  478.         gPreferences.sendFormat.whichFormats = kSMPNativeMask | kSMPStandardInterchangeMask;
  479.         gPreferences.sendFormat.whichNativeFormat = 0;
  480.         gPreferences.closeOnSend = false;
  481.         gPreferences.closeOptionsDialog = true;
  482.         gPreferences.expandOnCreate = true;
  483.         gPreferences.expandOnOpen = false;
  484.     }
  485.     
  486.     if (refNum!=0)
  487.         FSClose(refNum);
  488. }
  489.  
  490.  
  491. /* write our prefs global to disk */
  492.  
  493. void WritePrefs(void)
  494. {
  495.     FSSpec prefsSpec;
  496.     short refNum;
  497.     long count;
  498.     OSErr err;
  499.     
  500.     GetPrefsFolder(&prefsSpec);
  501.     
  502.     refNum = 0;
  503.     
  504.     err = FSpOpenDF(&prefsSpec,fsRdWrPerm,&refNum);
  505.     if (err!=noErr) {
  506.         err = FSpCreate(&prefsSpec,kAppCreator,kPrefsType,smRoman);
  507.         if (err==noErr)
  508.             err = FSpOpenDF(&prefsSpec,fsRdWrPerm,&refNum);
  509.     }
  510.  
  511.     if (err==noErr) {
  512.         count  = sizeof(MyPreferences);
  513.         err = FSWrite(refNum,&count,&gPreferences);
  514.     }
  515.     
  516.     if (refNum!=0)
  517.         FSClose(refNum);
  518. }
  519.  
  520.  
  521. /* get the folder the prefs file is in */
  522.  
  523. void GetPrefsFolder(FSSpec *fSpec)
  524. {
  525.     long gestResponse;
  526.     SysEnvRec sysEnv;
  527.     WDPBRec pBlock;
  528.     Str255 fName;
  529.     OSErr err;
  530.     
  531.     err = -1;
  532.     
  533.     // the new system 7 way
  534.     
  535.     if (TrapAvailable(_Gestalt) && 
  536.         (Gestalt(gestaltFindFolderAttr,&gestResponse)==noErr) &&
  537.         (gestResponse && (1<<gestaltFindFolderPresent))) {
  538.             err = FindFolder(kOnSystemDisk,kPreferencesFolderType,false,&fSpec->vRefNum,
  539.                             &fSpec->parID);
  540.     }
  541.  
  542.     // the old system 6 way
  543.     
  544.     if (err!=noErr) {
  545.         SysEnvirons(1,&sysEnv);
  546.         fName[0] = 0;
  547.         pBlock.ioVRefNum = sysEnv.sysVRefNum;
  548.         pBlock.ioNamePtr = fName;
  549.         pBlock.ioWDIndex = 0;
  550.         pBlock.ioWDProcID = 0;
  551.         pBlock.ioWDVRefNum = 0;
  552.         err = PBGetWDInfo(&pBlock,false);
  553.         if (err!=noErr) {
  554.             fSpec->vRefNum = -1;
  555.             fSpec->parID = fsRtDirID;
  556.         }
  557.     }
  558.     
  559.     GetResString(fSpec->name,kPrefsFileID,kPrefsFile);
  560. }
  561.  
  562.  
  563. #define    kButtonFrameInset    -4
  564. #define    kButtonFrameSize    3
  565. #define    kCntrActivate        0
  566. #define    kColorPortMask        0xc000
  567. #define    kActivateControl    0
  568.  
  569. /* draw outline for default button */
  570.  
  571. void MyDrawDefaultButtonOutline(DialogPtr theDialog,short theItem)
  572. {
  573.     short itemType;
  574.     Rect itemRect;
  575.     ControlHandle itemHandle;
  576.     PenState curPen;
  577.     short buttonOval;
  578.     RGBColor fgSaveColor,bgColor,newFGColor;
  579.     Boolean newGray;
  580.     WindowPtr oldPort;
  581.     Boolean isColor;
  582.     GDHandle targetDevice;
  583.     
  584.     // get the default button and draw a bold border around it
  585.     
  586.     GetDItem(theDialog,theItem,&itemType,(Handle *)&itemHandle,&itemRect);
  587.     GetPort(&oldPort);
  588.     SetPort((**itemHandle).contrlOwner);
  589.     GetPenState(&curPen);
  590.  
  591.     PenNormal();
  592.     InsetRect(&itemRect,kButtonFrameInset,kButtonFrameInset);
  593.     FrameRoundRect(&itemRect,16,16);
  594.  
  595.     buttonOval = ((itemRect.bottom-itemRect.top)/2) + 2;
  596.     if (((CGrafPtr)((**itemHandle).contrlOwner))->portVersion & kColorPortMask)
  597.         isColor = true;
  598.     else
  599.         isColor = false;
  600.     
  601.     if ((**itemHandle).contrlHilite != kActivateControl) {    // control is dimmed, so draw gray
  602.         newGray = false;
  603.         if (isColor) {
  604.             GetBackColor(&bgColor);
  605.             GetForeColor(&fgSaveColor);
  606.             newFGColor = fgSaveColor;
  607.             targetDevice = MyGetDeviceFromRect(&(**itemHandle).contrlRect);
  608.             newGray = GetGray(targetDevice,&bgColor,&newFGColor);
  609.         }
  610.         if (newGray)
  611.             RGBForeColor(&newFGColor);
  612.         else
  613.             #ifdef dangerousPattern
  614.             PenPat(qd.gray);
  615.             #else
  616.             PenPat(&qd.gray);
  617.             #endif
  618.         PenSize(kButtonFrameSize,kButtonFrameSize);
  619.         FrameRoundRect(&itemRect,buttonOval,buttonOval);
  620.         if (isColor)
  621.             RGBForeColor(&fgSaveColor);
  622.     }
  623.     else {
  624.         #ifdef dangerousPattern
  625.         PenPat(qd.black);
  626.         #else
  627.         PenPat(&qd.black);
  628.         #endif
  629.         PenSize(kButtonFrameSize,kButtonFrameSize);
  630.         FrameRoundRect(&itemRect,buttonOval,buttonOval);
  631.     }
  632.     
  633.     SetPenState(&curPen);
  634.     SetPort(oldPort);
  635. }
  636.  
  637.  
  638. GDHandle MyGetDeviceFromRect(Rect *localRect)
  639. {
  640.     GDHandle device;
  641.     Point wCenter;
  642.     
  643.     wCenter.v = localRect->bottom-localRect->top;
  644.     wCenter.h = localRect->right-localRect->left;
  645.     LocalToGlobal(&wCenter);
  646.     
  647.     device = GetDeviceList();
  648.     while (device) {
  649.         if (PtInRect(wCenter,&(**device).gdRect))
  650.             return device;
  651.         device = GetNextDevice(device);
  652.     }
  653.     
  654.     return GetMainDevice();
  655. }
  656.